package com.poetize.plus.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.poetize.plus.entity.dto.NoticeDTO;
import com.poetize.plus.entity.dto.page.NoticePageDTO;
import com.poetize.plus.entity.po.Notice;
import com.poetize.plus.entity.vo.NoticeVO;
import com.poetize.plus.entity.vo.page.NoticePageVO;
import com.poetize.plus.mapper.NoticeMapper;
import com.poetize.plus.service.NoticeService;
import com.poetize.plus.utils.BaseConstant;
import com.poetize.plus.utils.RedisUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @Author zuosy
 * @Date 2024/3/30 14:39
 **/
@Service
@RequiredArgsConstructor
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements NoticeService {

    private final RedisUtil redisUtil;

    @Override
    public Page<NoticePageVO> noticePage(NoticePageDTO noticePageDTO) {
        Page<Notice> noticePage = lambdaQuery()
                .like(StringUtils.hasText(noticePageDTO.getTitle()), Notice::getTitle, noticePageDTO.getTitle())
                .page(Page.of(noticePageDTO.getCurrent(), noticePageDTO.getSize()));

        Page<NoticePageVO> result = new Page<>();
        if (CollectionUtils.isEmpty(noticePage.getRecords())){
            return result;
        }
        result.setTotal(noticePage.getTotal());
        result.setRecords(NoticePageVO.convertPageList(noticePage.getRecords()));
        return result;
    }

    @Override
    public Boolean addNotice(NoticeDTO noticeDTO) {
        Notice checkTitle = lambdaQuery().eq(Notice::getTitle, noticeDTO.title()).one();
        if (Objects.nonNull(checkTitle)){
            throw new IllegalArgumentException("该公告已存在");
        }
        Notice notice = NoticeDTO.convertDTO(noticeDTO);
        boolean insert = baseMapper.insert(notice) > 0;
        if (!insert){
            throw new IllegalArgumentException("数据异常");
        }
        if (notice.getStatus()){
            redisUtil.setHomeRedis(BaseConstant.Redis.HOME_NOTICE, this::selectHomeNotice);
        }
        return true;
    }

    @Override
    public NoticeVO queryNotice(Long id) {
        Notice notice = baseMapper.selectById(id);
        return Optional.ofNullable(notice)
                .map(NoticeVO::convert)
                .orElseThrow(() -> new IllegalArgumentException("数据异常"));
    }

    @Override
    public Boolean updateNotice(NoticeDTO noticeDTO) {
        Notice checkTitle = lambdaQuery()
                .eq(Notice::getTitle, noticeDTO.title())
                .ne(Notice::getId, noticeDTO.id())
                .one();
        if (Objects.nonNull(checkTitle)){
            throw new IllegalArgumentException("该公告已存在");
        }
        Notice notice = NoticeDTO.convertDTO(noticeDTO);
        boolean update = baseMapper.updateById(notice) > 0;
        if (!update){
            throw new IllegalArgumentException("数据异常");
        }
        redisUtil.setHomeRedis(BaseConstant.Redis.HOME_NOTICE, this::selectHomeNotice);
        return true;
    }

    @Override
    public Boolean deleteNotice(Long id) {
        Notice notice = baseMapper.selectById(id);
        if (notice.getStatus()){
            throw new IllegalArgumentException("展示公告不可删除");
        }
        boolean delete = baseMapper.deleteById(id) > 0;
        if (!delete){
            throw new IllegalArgumentException("数据异常");
        }
        if (notice.getStatus()){
            redisUtil.setHomeRedis(BaseConstant.Redis.HOME_NOTICE, this::selectHomeNotice);
        }
        return true;
    }

    @Override
    public Boolean enable(Long id, Boolean status) {
        boolean update = lambdaUpdate()
                .set(Notice::getStatus, status)
                .eq(Notice::getId, id)
                .update();
        if (!update){
            throw new IllegalArgumentException("数据异常");
        }
        redisUtil.setHomeRedis(BaseConstant.Redis.HOME_NOTICE, this::selectHomeNotice);
        return true;
    }

    @Override
    public List<NoticeVO> getHomeNotice() {
        return redisUtil.getHomeRedis(BaseConstant.Redis.HOME_NOTICE, this::selectHomeNotice);
    }

    /**
     * 公告数据
     * @return
     */
    private List<NoticeVO> selectHomeNotice(){
        List<Notice> noticeList = lambdaQuery()
                .eq(Notice::getStatus, true)
                .list();
        return NoticeVO.convertList(noticeList);
    }
}
